package com.gitee.loyo.controller;

import com.gitee.loyo.Bridges;
import com.gitee.loyo.Global;
import com.gitee.loyo.Pages;
import com.gitee.loyo.page.BridgePage;
import com.gitee.loyo.utils.HttpUtils;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServerRequest;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;

import javax.ws.rs.*;
import java.io.StringWriter;

public class BridgeController {

    @GET
    @Path("/")
    public void openBridgePage(HttpServerRequest request, Promise<Void> promise){
        getBridges(request, promise);
    }

    @GET
    @Path("/bridge")
    public void getBridges(HttpServerRequest request, Promise<Void> promise){
        BridgePage bridgePage = new BridgePage();

        Template tmpl = Global.VELOCITY_ENGINE.getTemplate("vm/bridge.vm");
        VelocityContext ctx = new VelocityContext();
        ctx.put("page", bridgePage);
        StringWriter output = new StringWriter();
        tmpl.merge(ctx, output);
        Pages.renderPage(request.response(), output.toString());
        promise.complete();
    }

    @POST
    @Path("/bridge")
    public void saveBridge(HttpServerRequest request, Promise<Void> promise){
        Future.<Bridges.Bridge>future(p ->
            HttpUtils.getBodyAsJson(request, Bridges.Bridge.class, p)
        ).compose(bridge -> {
            if(bridge.domain == null || bridge.domain.isEmpty()){
                return Future.failedFuture("domain name is empty");
            }
            if(Bridges.contains(bridge.domain)){
                return Future.failedFuture("domain name is existed");
            }
            return Bridges.add(bridge);
        }).onComplete(ar -> completion(ar, request, promise));
    }

    @PUT
    @Path("/bridge")
    public void updateBridge(HttpServerRequest request, Promise<Void> promise){
        Future.<Bridges.Bridge>future(p ->
            HttpUtils.getBodyAsJson(request, Bridges.Bridge.class, p)
        ).compose(bridge -> {
            if(bridge.domain == null || bridge.domain.isEmpty()){
                return Future.failedFuture("domain name is empty");
            }
            if(!Bridges.contains(bridge.domain)){
                return Future.failedFuture("domain name is not existed");
            }
            return Bridges.update(bridge);
        }).onComplete(ar -> completion(ar, request, promise));
    }

    @DELETE
    @Path("/bridge")
    public void deleteBridge(HttpServerRequest request, Promise<Void> promise){
        Future.<Bridges.Bridge>future(p ->
            HttpUtils.getBodyAsJson(request, Bridges.Bridge.class, p)
        ).compose(bridge -> {
            if(bridge.domain == null || bridge.domain.isEmpty()){
                return Future.failedFuture("domain name is empty");
            }
            if(!Bridges.contains(bridge.domain)){
                return Future.failedFuture("domain name is not existed");
            }
            return Bridges.remove(bridge);
        }).onComplete(ar -> completion(ar, request, promise));
    }

    private void completion(AsyncResult<Void> ar, HttpServerRequest request, Promise<Void> promise){
        if(ar.failed()){
            ar.cause().printStackTrace();
            request.response().setStatusCode(400).end(ar.cause().getMessage());
        }else{
            request.response().setStatusCode(200).end();
        }
        promise.complete();
    }
}
